﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BusyReports.ReportingService;
using BusyReports.ReportExecution;
using System.Threading;
using System.IO;
using System.Net.Mail;
using System.Net;
using System.Text.RegularExpressions;
using System.ComponentModel;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Core.Objects;

namespace BusyReports
{
    public class BusyRunner
    {
        private BusyReportsEntities theContext;
        private BusySubscription theBusySubscription;
        private ReportingService2010 theReportingService;
        private ReportExecutionService theReportExecutionService;
        private CatalogItem theCatalogItem;
        private DateTime theStartTime;
        private BackgroundWorker theBackgroundWorker;
        public bool IsTestRun = false;

        public BusyRunner(BusySubscription aBusySubscription, BackgroundWorker aBackGroundWorker) //, BusyReportsEntities aContext
        {
            theStartTime = DateTime.Now;
            theContext = new BusyReportsEntities();//aContext;// 
            theBusySubscription = theContext.BusySubscriptions.Find(aBusySubscription.id);

            //theBusySubscription = aBusySubscription;
            theReportingService = new ReportingService2010();
            theReportingService.UseDefaultCredentials = true;
            theReportingService.Timeout = Timeout.Infinite;

            theReportExecutionService = new ReportExecutionService();
            theReportExecutionService.Credentials = System.Net.CredentialCache.DefaultCredentials;

            theReportExecutionService.Timeout = Timeout.Infinite;


            theBackgroundWorker = aBackGroundWorker;

        }
        public void run()
        {
            try
            {

                updateStatus(false, "Running");

                setCatalogItem();
                if (theCatalogItem == null) { throw new Exception("Report not Found in Reporting Services"); }



                // create temp dir to contain execution result
                string myTempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
                Directory.CreateDirectory(myTempDirectory);



                if (theBusySubscription.Type == "MAIL")
                {
                    log("Start Email Delivery");

                    executeMailMessage();

                    log("End Email Delivery");

                }

                if (theBusySubscription.Type == "FILE")
                {
                    log("Start File Delivery");

                    executeToFile();

                    log("End File Delivery");
                }

                updateStatus(true, "Success");

            }
            catch (Exception ex)
            {
                log(String.Format("Exception {0} \r\n InnerException", ex.Message, ex.InnerException), true);
                updateStatus(true, "Error");
                return;
            }

        }

        private void executeToFile()
        {
            theContext.Entry(theBusySubscription).Reference(u => u.BusyFileSubscription).Load();
            theContext.Entry(theBusySubscription).Collection(u => u.BusySubscriptionsParameters).Load();

            string myFileName = "";

            if (IsTestRun)
            {
                myFileName = replaceParametersInString(theBusySubscription.BusyFileSubscription.Path);
                myFileName = myFileName.Substring(myFileName.LastIndexOf("\\"), myFileName.Length - myFileName.LastIndexOf("\\"));
                myFileName = Properties.Settings.Default.TestPath + myFileName;
            }
            else
            { myFileName = replaceParametersInString(theBusySubscription.BusyFileSubscription.Path); }

            if (myFileName != "" & File.Exists(myFileName)) File.Delete(myFileName);
            
            // check if the directory exists
            string myDirectory = Path.GetDirectoryName(myFileName);

            if (! Directory.Exists(myDirectory))
            {
                Directory.CreateDirectory(myDirectory); 
            }

            string myPathToFile = executeReport(theBusySubscription.BusyFileSubscription.Format, myFileName);
        }

        private void executeMailMessage()
        {
            theContext.Entry(theBusySubscription).Reference(u => u.BusyMailSubscription).Load();
            theContext.Entry(theBusySubscription).Collection(u => u.BusySubscriptionsParameters).Load();


            string myTempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            try
            {
                // create temp dir to contain execution result
                // this is a dir because the attachement needs a specific name, and it-s maybe already existing

                Directory.CreateDirectory(myTempDirectory);

                System.Net.Mail.MailMessage myMessage = new System.Net.Mail.MailMessage();

                buildMessage(myTempDirectory, myMessage);

                sendEmail(myMessage);

                LogEmailRecipients(myMessage);

                myMessage.Dispose();
            }
            catch (Exception)
            { throw; }
            finally
            {
                cleanupTempFiles(myTempDirectory);
            }

        }

        private void buildMessage(string myTempDirectory, System.Net.Mail.MailMessage myMessage)
        {
            string myPathToHtmlBody = "";


            if (theBusySubscription.BusyMailSubscription.ReportInMailBody == true)
            {
                log("Processing Report for Email Body");
                myPathToHtmlBody = executeReport("HTML4.0", myTempDirectory + "\\" + Guid.NewGuid().ToString());
                log("End Processing Report for Email Body");
            }
            string myPathToAttachement = "";
            if (theBusySubscription.BusyMailSubscription.ReportAsAttachement == true)
            {
                log("Processing Report for Email Attachement");
                string myAttachementName = replaceParametersInString(theBusySubscription.BusyMailSubscription.AttachementName);
                if (myAttachementName == null) myAttachementName = theCatalogItem.Name;
                if (myAttachementName == String.Empty) myAttachementName = theCatalogItem.Name;
                myAttachementName = myTempDirectory + "\\" + myAttachementName;
                myAttachementName = appendFileExtension(myAttachementName);

                myPathToAttachement = executeReport(theBusySubscription.BusyMailSubscription.AttachementFormat, myAttachementName);
                log("End Processing Report for Email Attachement");
            }


            if (IsTestRun)
            {
                if (theBusySubscription.BusyMailSubscription.To != null & theBusySubscription.BusyMailSubscription.To.Length > 0) myMessage.To.Add(cleanupEmailListString(Properties.Settings.Default.TestEmail));
                if (theBusySubscription.BusyMailSubscription.Cc != null & theBusySubscription.BusyMailSubscription.Cc.Length > 0) myMessage.CC.Add(cleanupEmailListString(Properties.Settings.Default.TestEmail));
                if (theBusySubscription.BusyMailSubscription.Bcc != null & theBusySubscription.BusyMailSubscription.Bcc.Length > 0) myMessage.Bcc.Add(cleanupEmailListString(Properties.Settings.Default.TestEmail));
            }
            else
            {
                if (theBusySubscription.BusyMailSubscription.To != null & theBusySubscription.BusyMailSubscription.To.Length > 0) myMessage.To.Add(cleanupEmailListString(theBusySubscription.BusyMailSubscription.To));
                if (theBusySubscription.BusyMailSubscription.Cc != null & theBusySubscription.BusyMailSubscription.Cc.Length > 0) myMessage.CC.Add(cleanupEmailListString(theBusySubscription.BusyMailSubscription.Cc));
                if (theBusySubscription.BusyMailSubscription.Bcc != null & theBusySubscription.BusyMailSubscription.Bcc.Length > 0) myMessage.Bcc.Add(cleanupEmailListString(theBusySubscription.BusyMailSubscription.Bcc));
            }
            string mySubject = replaceParametersInString(theBusySubscription.BusyMailSubscription.Subject);
            myMessage.Subject = mySubject;
            myMessage.From = new System.Net.Mail.MailAddress(theBusySubscription.BusyMailSubscription.From == null ? "" : theBusySubscription.BusyMailSubscription.From);


            if (myMessage.To.Count + myMessage.CC.Count + myMessage.Bcc.Count == 0)
            {
                log("no recipients in email.", true);
                throw new Exception("no recipients in email!");
            }


            if (myPathToHtmlBody != "")
            {
                insertHtmlBody(myPathToHtmlBody, myMessage);
            }
            else
            {
                myMessage.IsBodyHtml = true;
                myMessage.Body = replaceParametersInString( theBusySubscription.BusyMailSubscription.Comment);
            }

            if (myPathToAttachement != "")
            {
                myMessage.Attachments.Add(new Attachment(myPathToAttachement));
            }
        }

        private string appendFileExtension(string myAttachementName)
        {
            if (theBusySubscription.BusyMailSubscription.AttachementFormat == "EXCEL") myAttachementName += ".xls";
            if (theBusySubscription.BusyMailSubscription.AttachementFormat == "PDF") myAttachementName += ".pdf";
            if (theBusySubscription.BusyMailSubscription.AttachementFormat == "MHTML") myAttachementName += ".mht";
            if (theBusySubscription.BusyMailSubscription.AttachementFormat == "CSV") myAttachementName += ".csv";
            return myAttachementName;
        }

        private string replaceParametersInString(string aString)
        {
            string myString = aString;

            foreach (BusySubscriptionsParameter myParameter in theBusySubscription.BusySubscriptionsParameters)
            {
                myString = myString.Replace("@" + myParameter.ParameterName, myParameter.ParameterValue);
            }
            return myString;
        }
        private string cleanupEmailListString(string aEmailList)
        {
            if (aEmailList == null) aEmailList = "";
            string myCleanedEmailList = aEmailList.Replace(";", ",");
            while (myCleanedEmailList.Contains(" "))
            {
                myCleanedEmailList = myCleanedEmailList.Replace(" ", "");
            }
            return myCleanedEmailList;

        }

        private void sendEmail(System.Net.Mail.MailMessage myMessage)
        {
            SmtpClient mySmtpClient = getSmtpClient();

            int myRetryCount = 0;
            while (myRetryCount < 5)
            {
                try
                {
                    mySmtpClient.Send(myMessage);
                    log(String.Format("Mail sent after {0} retries", myRetryCount));
                    break;
                }
                catch (Exception ex)
                {
                    log(String.Format(@"Error sending mail, retrying in 10s. Error {0}
                   InnerException {1}", ex.Message, ex.InnerException));

                    System.Threading.Thread.Sleep(10000);
                    myRetryCount++;
                    if (myRetryCount >= 5)
                    {
                        log(String.Format("Error sending Mail after {0} retries", myRetryCount), true);
                        throw;
                    }

                }
            }
            mySmtpClient.Dispose();
        }

        private SmtpClient getSmtpClient()
        {
            try
            {
                System.Net.Mail.SmtpClient mySmtpClient = new System.Net.Mail.SmtpClient(Properties.Settings.Default.smtpServer);
                mySmtpClient.Port = Convert.ToInt32(Properties.Settings.Default.smtpPort);
                mySmtpClient.EnableSsl = Convert.ToBoolean(Properties.Settings.Default.stmpUseSSL);

                if (Convert.ToBoolean(Properties.Settings.Default.smtpUseAuth))
                {
                    mySmtpClient.Credentials = new NetworkCredential(Properties.Settings.Default.smtpUser, Properties.Settings.Default.smtpPassword);
                }

                return mySmtpClient;
            }
            catch (Exception)
            {
                log("invalid smtp settings ", true);
                throw;
            }
        }

        private void insertHtmlBody(string aPathToHtml, System.Net.Mail.MailMessage myMessage)
        {
            string myBody = "<body>" + File.ReadAllText(aPathToHtml) + "</body>";
            // see sendEmailMHTML for sending a MHTML file generated by reporting services, it does not work with our exchange server however (email is not delivered, no errors)

            // this is the html4 body from html4 renderer
            List<string> myGraphs = fetchLinksFromSource(myBody);
            int k = 1;
            List<LinkedResource> myImages = new List<LinkedResource>();
            foreach (string url in myGraphs)
            {
                using (WebClient Client = new WebClient())
                {
                    string myFile = Path.GetTempFileName();
                    Client.UseDefaultCredentials = true;
                    Client.DownloadFile(url, myFile);
                    LinkedResource img = new LinkedResource(myFile);
                    img.ContentId = "tata" + k;
                    img.ContentType.MediaType = "image/gif";
                    myBody = myBody.Replace(url, "cid:tata" + k);
                    k++;
                    myImages.Add(img);
                }
            }
            if (theBusySubscription.BusyMailSubscription.Comment != "")
            {
                myBody = insertCommentInBody(myBody, replaceParametersInString( theBusySubscription.BusyMailSubscription.Comment));
            }

            if (theBusySubscription.BusyMailSubscription.IncludeLinkToReport == true)
            {
                myBody = insertLinkInBody(myBody);
            }

            //myBody = removeMinWidths(myBody);
            AlternateView htmlView = AlternateView.CreateAlternateViewFromString(myBody, null, "text/html");
            foreach (LinkedResource i in myImages)
            { htmlView.LinkedResources.Add(i); }

            myMessage.AlternateViews.Add(htmlView);
        }

        private void LogEmailRecipients(MailMessage myMessage)
        {
            log(String.Format("Mail From: {0}", myMessage.From));

            foreach (MailAddress a in myMessage.To)
            {
                log(String.Format("Mail To: {0}", a.Address));
            }
            foreach (MailAddress a in myMessage.CC)
            {
                log(String.Format("Mail Cc: {0}", a.Address));
            }
            foreach (MailAddress a in myMessage.Bcc)
            {
                log(String.Format("Mail Bcc: {0}", a.Address));
            }
        }

        private string insertLinkInBody(string aHtml)
        {
            string myUrl = Properties.Settings.Default.BusyReports_ReportingService_ReportingService2010 + "/Pages/Report.aspx?ItemPath=";
            myUrl += theBusySubscription.ReportPath.Replace("/", "%2f").Replace(" ", "&#43;");


            foreach (BusySubscriptionsParameter p in theBusySubscription.BusySubscriptionsParameters)
            {
                if (p.ParameterUseDefault == true) continue;
                myUrl += "&" + p.ParameterName + "=" + p.ParameterValue;
            }
            string myLink = "<br><a style=\"font-family:Arial;font-size:10pt;font-weight:700\" href=\"" + myUrl + "\">" + theCatalogItem.Name + "</a><br>";
            string myHtml = Regex.Replace(aHtml, @"<body.*?>", delegate(Match match)
            {
                string v = match.ToString();
                return v + myLink;
            });
            return myHtml;

        }
        private static string insertCommentInBody(string aHtml, string aComment)
        {
            string myHtml = Regex.Replace(aHtml, @"<body.*?>", delegate(Match match)
            {
                string v = match.ToString();
                return v + "<p style=\"font-family:Arial;font-size:10pt;font-weight:700\">" + aComment + "</p>";
            });
            return myHtml;

        }



        private static List<string> fetchLinksFromSource(string htmlSource)
        {
            List<string> links = new List<string>();
            string regexImgSrc = @"<img[^>]*?src\s*=\s*[""']?([^'"" >]+?)[ '""][^>]*?>";
            MatchCollection matchesImgSrc = Regex.Matches(htmlSource, regexImgSrc, RegexOptions.IgnoreCase | RegexOptions.Singleline);
            foreach (Match m in matchesImgSrc)
            {
                string href = m.Groups[1].Value;
                links.Add(href);
            }
            return links;
        }
        private void cleanupTempFiles(string myPath)
        {
            if (myPath != "" & File.Exists(myPath))
            {
                try
                {
                    FileInfo myFileInfo = new FileInfo(myPath);
                    FileInfo myTempFileInfo = new FileInfo(Path.GetTempPath());
                    File.Delete(myPath);
                    if (myFileInfo.Directory.Parent.FullName == myTempFileInfo.Directory.FullName)
                    {
                        myFileInfo.Directory.Delete();
                    }
                }
                catch (Exception ex)
                {
                    log(String.Format("error cleaning up temp files: {0}", ex.Message), false, true);
                }

            }
        }
        private void setCatalogItem()
        {
            ReportingService.CatalogItem[] myCatalogItems = theReportingService.ListChildren("/", true);

            theCatalogItem = null;
            foreach (CatalogItem i in myCatalogItems)
            {
                if (i.TypeName == "Report" & i.Path == theBusySubscription.ReportPath)
                {
                    theCatalogItem = i;
                }
            }


        }
        private void updateStatus(bool aUpdateLastRun, string aLastStatus)
        {
            if (aUpdateLastRun)
            {
                theBusySubscription.LastRun = DateTime.Now;
                theBusySubscription.LastRunDurationSeconds = (int?)(DateTime.Now - theStartTime).TotalSeconds;
            }
            theBusySubscription.LastStatus = aLastStatus;

            try
            {
                theContext.SaveChanges();
            }
            catch (DbUpdateConcurrencyException ex)
            {
                var myContext = ((IObjectContextAdapter)theContext).ObjectContext;
                myContext.Refresh(RefreshMode.ClientWins, ex.Entries.Select(e => e.Entity));
            }
            catch (Exception ex)
            {
                log(ex.Message);
                throw;
            }


            theBackgroundWorker.ReportProgress(1);


        }
        private void log(string aMessage, bool IsError = false, bool IsWarning = false)
        {
            string myMessage = String.Format("{1}: ID {0}: ", theBusySubscription.id, DateTime.Now)
                 + aMessage;
            if (IsError) myMessage = "ERROR:" + myMessage;
            else if (IsWarning) myMessage = "Warning:" + myMessage;
            Console.WriteLine(myMessage);
            if (theBusySubscription.log == null) theBusySubscription.log = "";
            theBusySubscription.log += myMessage + "\r\n";
        }


        private string executeReport(string aFormat, string aFileName)
        {
            // adapted from http://technet.microsoft.com/en-us/library/aa258532%28v=sql.80%29.aspx

            // ItemParameters are the parameters found on Reporting Services
            ItemParameter[] myItemParameters = theReportingService.GetItemParameters(theBusySubscription.ReportPath, null, true, null, null);
            //forRendering needs to be true if validvalues is needed


            //theBusySubscription.BusySubscriptionsParameters are the parameters configured

            //myExecutionParameters are the parameters that will be used for execution
            List<ReportExecution.ParameterValue> myExecutionParameters = new List<ReportExecution.ParameterValue>();

            // after the execution, execInfo.Parameters will contain the parameters really executed (i.e with defaut values replaced)


            // loop trough ItemParameters
            // find matching BusySubscriptionsParameters
            // create ReportExecution.ParameterValue and add them to myExecutionParameters
            foreach (ItemParameter myItemParameter in myItemParameters.OrderBy(a => a.Name))
            {
                if (myItemParameter.PromptUser == false) continue;
                BusySubscriptionsParameter myParameter = (from a in theBusySubscription.BusySubscriptionsParameters
                                                          where a.ParameterName == myItemParameter.Name
                                                          select a).FirstOrDefault();
                if (myParameter == null)
                {
                    log(String.Format("Parameter {0} not configured", myItemParameter.Name));
                    continue;
                }

                if (myParameter.ParameterUseDefault == true)
                {
                    log(String.Format("Parameter {0} set to default", myParameter.ParameterName));
                    continue;
                }
                else
                {
                    if (myParameter.ParameterValue != null && myParameter.ParameterValue.StartsWith("["))// multivalue
                    {
                        //string myParameterValue = myParameter.ParameterValue.Replace("[", "").Replace("]", "");
                        string myParameterValue = myParameter.ParameterValue.Substring(myParameter.ParameterValue.IndexOf("["),
                            myParameter.ParameterValue.LastIndexOf("]"));

                        foreach (string s in myParameterValue.Split(","[0]))
                        {
                            myExecutionParameters.Add(getExecutionParameter(myItemParameter.ValidValues, myParameter.ParameterName, s));
                            log(String.Format("Parameter {0} set to {1} (Mutliselect)", myParameter.ParameterName, s));
                        }
                    }
                    else if (myParameter.ParameterValue != null && myParameter.ParameterValue.StartsWith("!["))// multivalue exclude
                    {
                        string[] myParameterExcludeValues = myParameter.ParameterValue.Substring(myParameter.ParameterValue.IndexOf("["),
                           myParameter.ParameterValue.LastIndexOf("]")).Split(","[0]);
                        //string[] myParameterExcludeValues = myParameter.ParameterValue.Replace("![", "").Replace("]", "").Split(","[0]);

                        foreach (BusyReports.ReportingService.ValidValue s in myItemParameter.ValidValues)
                        {
                            if (!myParameterExcludeValues.Contains(s.Value) && !s.Value.StartsWith("["))
                            {
                                myExecutionParameters.Add(getExecutionParameter(myItemParameter.ValidValues, myParameter.ParameterName, s.Value));
                                log(String.Format("Parameter {0} set to {1} (Mutliselect, exclude)", myParameter.ParameterName, s));
                            }
                        }
                    }
                    else
                    {
                        myExecutionParameters.Add(getExecutionParameter(myItemParameter.ValidValues, myParameter.ParameterName, myParameter.ParameterValue));
                        log(String.Format("Parameter {0} set to {1} (Mutliselect, exclude)", myParameter.ParameterName, myParameter.ParameterValue == null ? "<null>" : myParameter.ParameterValue));
                    }
                }
                // update myItemParameters with new values (in case they are affected by already set parameters)
                myItemParameters = theReportingService.GetItemParameters(theBusySubscription.ReportPath, null, true, getParameterValue(myExecutionParameters).ToArray(), null);
            }



            // Render arguments
            byte[] result = null;

            //string format = "MHTML";
            //XML, NULL, CSV, IMAGE, PDF, HTML4.0, HTML3.2, MHTML, EXCEL, and HTMLOWC.
            string historyID = null;
            //http://stackoverflow.com/questions/13533634/html4-0-ssrs-report-is-squashed-in-outlook-when-sent-with-system-net-mail-is-it

            string devInfo = @"<DeviceInfo><OutlookCompat>True</OutlookCompat><HTMLFragment>True</HTMLFragment></DeviceInfo>";
            string encoding;
            string mimeType;
            string extension;
            ReportExecution.Warning[] warnings = null;
            string[] streamIDs = null;

            ExecutionInfo execInfo = new ExecutionInfo();
            ExecutionHeader execHeader = new ExecutionHeader();

            theReportExecutionService.ExecutionHeaderValue = execHeader;

            execInfo = theReportExecutionService.LoadReport(theBusySubscription.ReportPath, historyID);

            theReportExecutionService.SetExecutionParameters(myExecutionParameters.ToArray(), "en-us");
            String SessionId = theReportExecutionService.ExecutionHeaderValue.ExecutionID;

            result = theReportExecutionService.Render(aFormat, devInfo, out extension, out encoding, out mimeType, out warnings, out streamIDs);

            execInfo = theReportExecutionService.GetExecutionInfo();


            foreach (ReportParameter myExecutedParameter in execInfo.Parameters)
            {
                BusySubscriptionsParameter myBusySubscriptionsParameter = (from a in theBusySubscription.BusySubscriptionsParameters
                                                                           where a.ParameterName == myExecutedParameter.Name
                                                                           select a).FirstOrDefault();
                if (myBusySubscriptionsParameter == null) continue;

                if (myBusySubscriptionsParameter.ParameterUseDefault == true)
                {
                    if (myExecutedParameter.DefaultValues.Count() == 1)
                    {
                        myBusySubscriptionsParameter.ParameterValue = myExecutedParameter.DefaultValues[0];

                        log(String.Format("Default Parameter {0} was set to {1} at execution time", myExecutedParameter.Name, myExecutedParameter.DefaultValues[0]));
                    }
                    else
                    {
                        string myParameterValue = "[" + string.Join(",", myExecutedParameter.DefaultValues) + "]";
                        myBusySubscriptionsParameter.ParameterValue = myParameterValue;
                        log(String.Format("Default Parameter {0} was set to {1} (multiselect) at execution time", myExecutedParameter.Name, myParameterValue));

                    }
                }
            }

            string myFile = aFileName;
            try
            {
                if (File.Exists(myFile)) File.Delete(myFile);
            }
            catch (Exception)
            {
                // file locked @#$@.. f... it
                myFile = myFile.Replace(theCatalogItem.Name, theCatalogItem.Name + "_" + DateTime.Now.Ticks);
            }
            FileStream stream = File.Create(myFile, result.Length);

            stream.Write(result, 0, result.Length);

            stream.Close();
            stream.Dispose();
            return myFile;

        }

        private List<ReportingService.ParameterValue> getParameterValue(List<ReportExecution.ParameterValue> aParameterValueList)
        {
            List<ReportingService.ParameterValue> myParameters = new List<ReportingService.ParameterValue>();
            foreach (ReportExecution.ParameterValue v in aParameterValueList)
            {
                ReportingService.ParameterValue myParameterValue = new ReportingService.ParameterValue();
                myParameterValue.Name = v.Name;
                myParameterValue.Value = v.Value;
                myParameters.Add(myParameterValue);
            }
            return myParameters;
        }
        private BusyReports.ReportExecution.ParameterValue getExecutionParameter(BusyReports.ReportingService.ValidValue[] aValidValues, string aName, string aValue)
        {
            ReportExecution.ParameterValue myExecutionParameter = new ReportExecution.ParameterValue();

            bool valid = false;

            if (aValidValues != null)
            {
                foreach (BusyReports.ReportingService.ValidValue v in aValidValues)
                {
                    if (v.Value == aValue) { valid = true; break; }
                }
                if (!valid)
                {
                    log(String.Format("Parameter {0} invalid value {1}", aName, aValue), false, true);
                }
            }

            myExecutionParameter.Name = aName;
            myExecutionParameter.Value = aValue;
            return myExecutionParameter;
        }

    }
}
